/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [TimePanel.java]
 * Creation Date        [11-Jul-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_02_gui.clock_V2.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;
import javax.swing.Timer;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * 时间面板
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class TimePanel extends JPanel implements ActionListener, ChangeListener {

	private static final long serialVersionUID = 1753337067597504984L;

	/** 面板的宽度 */
	private final int width = 190;
	/** 面板的高度 */
	private final int height = 190;
	/** 显示时间的组件 */
	private JSpinner time = null;
	/** 日期时间类 */
	private final GregorianCalendar calendar = CalendarPanel.calendar;
	/**  */
	private Timer timer = null;
	/** 时 */
	private int hour = 0;
	/** 分 */
	private int minute = 0;
	/** 秒 */
	private int second = 0;
	/** 表盘的中心点 */
	private final int r = 65;

	/**
	 * 构造一个时间显示类
	 */
	public TimePanel() {
		setSize(width, height);
		setPreferredSize(new Dimension(width, height));
		setBorder(new TitledBorder(new LineBorder(Color.GRAY), "时间[T]"));
		setLayout(new FlowLayout(FlowLayout.CENTER, 7, 13));

		hour = calendar.get(GregorianCalendar.HOUR_OF_DAY);
		minute = calendar.get(GregorianCalendar.MINUTE);
		second = calendar.get(GregorianCalendar.SECOND);

		SpinnerDateModel model = new SpinnerDateModel(calendar.getTime(),
				new Date(0), null, GregorianCalendar.SECOND);

		time = new JSpinner(model);
		time.setEditor(new JSpinner.DateEditor(time, "HH: mm: ss"));
		time.setSize(120, 20);
		time.setLocation((width - time.getWidth()) / 2, height - 30);
		time.addChangeListener(this);

		setLayout(null);
		add(time);

		timer = new Timer(1000, this);
		timer.start();

	}

	/**
	 * 时间的修改<br>
	 * 每个1秒钟, 秒钟自加1,每个60秒, 分针自加1, 秒针为0,每个60分, 时针自加1, 分针变为0,每隔24时, 时针变为0
	 */
	private void changeTime() {
		second++;
		if (second == 60) {
			minute++;
			second = 0;
		}
		if (minute == 60) {
			hour++;
			minute = 0;
		}
		if (hour == 24)
			hour = 0;
	}

	/**
	 * 完成表盘和表针的绘制
	 */
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		paintWatchFace(g);
		paintTime(g);
	}

	/**
	 * 表盘的绘制<br>
	 */
	public void paintWatchFace(Graphics g) {

		Color c = g.getColor();
		g.translate(width / 2, r + 20);// 移动原点到(r,r)

		for (int i = 0; i <= 360; i += 6) {
			if (i % 30 == 0) {
				g.setColor(new Color(0, 255, 255));
				g.fillOval((int) (Math.cos(Math.toRadians(i)) * r),
						(int) (Math.sin(Math.toRadians(i)) * r), 3, 3);
			} else {
				g.setColor(Color.GRAY);
				g.fillOval((int) (Math.cos(Math.toRadians(i)) * r),
						(int) (Math.sin(Math.toRadians(i)) * r), 2, 2);
			}
		}
		g.setColor(c);
	}

	/**
	 * 绘制时针, 分针, 秒针<br>
	 */
	public void paintTime(Graphics g) {
		Color c = g.getColor();
		g.setColor(new Color(0, 128, 128));
		// 绘制时针
		int hourA[] = {
				(int) (Math.cos(Math
						.toRadians(hour * 30 + minute / 12 * 6 - 90)) * r * 0.7),
				(int) (Math.cos(Math.toRadians(hour * 30 + minute / 12 * 6))
						* r * 0.06),
				(int) (Math.cos(Math
						.toRadians(hour * 30 + minute / 12 * 6 + 90)) * r * 0.12),
				(int) (Math.cos(Math.toRadians(hour * 30 + minute / 12 * 6
						+ 180))
						* r * 0.06) };
		int hourB[] = {
				(int) (Math.sin(Math
						.toRadians(hour * 30 + minute / 12 * 6 - 90)) * r * 0.7),
				(int) (Math.sin(Math.toRadians(hour * 30 + minute / 12 * 6))
						* r * 0.06),
				(int) (Math.sin(Math
						.toRadians(hour * 30 + minute / 12 * 6 + 90)) * r * 0.12),
				(int) (Math.sin(Math.toRadians(hour * 30 + minute / 12 * 6
						+ 180))
						* r * 0.06) };
		g.fillPolygon(hourA, hourB, hourA.length);

		// 绘制分针
		g.setColor(new Color(0, 128, 128));
		int minuteA[] = {
				(int) (Math.cos(Math.toRadians(minute * 6 - 90)) * r * 0.8),
				(int) (Math.cos(Math.toRadians(minute * 6)) * r * 0.05),
				(int) (Math.cos(Math.toRadians(minute * 6 + 90)) * r * 0.16),
				(int) (Math.cos(Math.toRadians(minute * 6 + 180)) * r * 0.05) };
		int minuteB[] = {
				(int) (Math.sin(Math.toRadians(minute * 6 - 90)) * r * 0.8),
				(int) (Math.sin(Math.toRadians(minute * 6)) * r * 0.05),
				(int) (Math.sin(Math.toRadians(minute * 6 + 90)) * r * 0.16),
				(int) (Math.sin(Math.toRadians(minute * 6 + 180)) * r * 0.05) };
		g.fillPolygon(minuteA, minuteB, minuteA.length);

		// 绘制秒针
		g.setColor(Color.black);
		g.drawLine(0, 0,
				(int) (Math.cos(Math.toRadians(second * 6 - 90)) * r * 0.9),
				(int) (Math.sin(Math.toRadians(second * 6 - 90)) * r * 0.9));
		g.setColor(c);
	}

	/**
	 * 每个一秒出发重绘时针, 分针, 秒针的重绘, 还有JSpinner的重新显示
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		changeTime();
		repaint();
		time.setValue(time.getNextValue());

	}

	@Override
	public void stateChanged(ChangeEvent e) {
		// timer.stop();
	}
}
